home *** CD-ROM | disk | FTP | other *** search
- /* Support routines for GNU DIFF.
- Copyright (C) 1988 Free Software Foundation, Inc.
-
- This file is part of GNU DIFF.
-
- GNU DIFF is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU DIFF General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU DIFF, but only under the conditions described in the
- GNU DIFF General Public License. A copy of this license is
- supposed to have been given to you along with GNU DIFF so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies. */
-
- #include <MacHeaders>
- #include <Packages.h>
- #include <stdarg.h>
- #define GDIFF_MAIN
- #include "diff.h"
- #include "diff3.h"
- #include "regex.h"
-
- int no_discards;
-
- int allocatedBlocks = 0;
-
- #include "QuedProcs.h"
-
- void _main(void); /* Called at startup. */
-
- /*
- * These are the callbacks that the "diff" module changes. The following global variables hold
- * the original callback routines, so that we can call them when needed. Each one is overridden
- * the the same function name except preceeded with the word "Diff". For example, ReadPreferences
- * is overridden with "DiffReadPreferences". Its original procedure pointer is stored in "OriginalReadPreferences".
- */
- /*
- * We need to save more preferences, so that we can remember what the settings were next time
- * the program starts up.
- */
- static void (*OriginalReadPreferences) (void);
- static void (*OriginalSavePreferences) (void);
- /*
- * We need to move more text markers when text is inserted and deleted. This way, the change bars on
- * the left side are updated when text is inserted, etc.
- */
- static int (*OriginalOffsetTextMarkers) (VTE, long location, long numDelete, long numInsert);
- /*
- * We modify the ShowLeftMarginIcons, GetQuedIconsWidth, and ClickLeftMarginIcons so that the change
- * bars will appear on the left side of the windows that have been run through a "diff".
- */
- static int (*OriginalShowLeftMarginIcons) (VTE, long startl, long end, Rect *lineRect, int iconPosition);
- static int (*OriginalGetQuedIconsWidth) (VTE);
- static int (*OriginalClickLeftMarginIcons) (VTE w, long sel, Point where, int *barPosition);
- /*
- * Since the "diff" module adds supplemental information to a window, it needs to dispose that information
- * when that window is closed. Overriding the dispose procedure for a window allows us to do this.
- */
- static void (*OriginalKillTextWindow) (VTE);
- /*
- * This is the end of the functions and procedures we override.
- */
-
- /*
- * These are the items in the "Two Files:" popup menu that appears in the
- * Differences Options... dialog.
- */
- enum CompareResult2
- {
- cShowChangeBars2,
- cComposite2,
- cIfdef2,
- cUNIX2,
- cUnified2,
- cED2,
- cForwardED2,
- cRCS2
- };
-
- /*
- * These are the items in the "Three Files:" popup menu that appears in the
- * Differences Options... dialog.
- */
- enum CompareResult3
- {
- cShowChangeBars3,
- cComposite3,
- cMerge3,
- cUNIX3
- };
-
- /*
- * These are the item numbers of each item in the Differences Options... dialog.
- */
- enum DiffOptionsDialogItems
- {
- DITEM_OK = 1,
- DITEM_CANCEL,
- DITEM_STAT3,
- DITEM_STAT4,
- DITEM_MULTBLANK,
- DITEM_ALLBLANK,
- DITEM_BLANKLINES,
- DITEM_CASE,
- DITEM_LINESCONTAINING,
- DITEM_EDITLINESCONTAINING,
- DITEM_FASTCOMPARE,
- DITEM_STAT12,
- DITEM_STAT13,
- DITEM_TWOFILES,
- DITEM_STAT15,
- DITEM_THREEFILES,
- DITEM_SHOWCONTEXT,
- DITEM_EDITCONTEXTAMOUNT,
- DITEM_STAT19,
- DITEM_SHOWPRECEEDING,
- DITEM_EDITSHOWPRECEEDING,
- DITEM_USER22,
- DITEM_REPLACETOP,
- DITEM_STAT24,
- DITEM_SHOWCHANGEBARS,
- DITEM_STAT26,
- DITEM_STAT27,
- DITEM_IFDEF,
- DiffOptionsDialogItemsNum,
- DITEM_FIRSTUNIX = DITEM_SHOWCONTEXT,
- DITEM_LASTUNIX = DITEM_EDITSHOWPRECEEDING,
- DITEM_FIRSTWINDOW = DITEM_REPLACETOP,
- DITEM_LASTWINDOW = DITEM_REPLACETOP,
- DITEM_FIRSTSHOWCHANGEBARS = DITEM_SHOWCHANGEBARS,
- DITEM_LASTSHOWCHANGEBARS = DITEM_SHOWCHANGEBARS,
- DITEM_FIRSTIFDEF = DITEM_STAT26,
- DITEM_LASTIFDEF = DITEM_IFDEF
- };
-
- /*
- * DIFF_PIXELS is the number of pixels that each change bar column takes up. Thus, a window
- * with three change bar columns will have 30 pixels for the change bars.
- */
- #define DIFF_PIXELS 10
-
- /*
- * When SwapStructureWithDialog is called, the values in this structure
- * are taken from the settings of the items in the Differences Options...
- * dialog, or are deposited to the items in this dialog.
- */
- static struct DiffOptions
- {
- int ignoreMultipleBlanks;
- int ignoreAllBlanks;
- int ignoreBlankLines;
- int ignoreCase;
- int ignoreLinesContaining;
- int linesContainingLength;
- char linesContaining[256];
- int fastCompare;
- int presentCompareResult2;
- int presentCompareResult3;
- int isContext;
- int contextLines;
- int linePreceedingIs;
- int linePreceedingLength;
- char linePreceeding[256];
- int replaceTopWindow;
- int showChangeBars;
- int ifdefLength;
- char ifdef[256];
- } diffOptions;
-
- /*
- * This is a Handle to text for stdout. When something in the "diff" program sends text
- * to stdout or stderr, it gets appended to outFileHandle.
- */
- Handle outFileHandle;
-
- /*
- * This is a private structure to the QUED Diff Module. It stores some information
- * for each change bar.
- */
- struct ChangeBar
- {
- long start;
- long end;
- char whichColumns; /* These are various flags explaining the type of difference. */
- char filler;
- int scriptNumber;
- long filler2;
- };
-
- /* These are the flags for "whichColumns" */
- #define cColumn1 1 /* Put this change in the first column. */
- #define cColumn2 2 /* Put this change in the second column */
- #define cColumn3 4 /* Put this change in the third column */
- #define cFillBlack1 8 /* Fill this one in black. Indicates a "change" rather than in "insert". */
- #define cFillBlack2 16 /* Fill this one in black. Indicates a "change" rather than in "insert". */
- #define cFillBlack3 32 /* Fill this one in black. Indicates a "change" rather than in "insert". */
-
- /*
- * This is a private structure to the QUED Diff Module. It stores some information
- * for each window AFTER that window is run through a "diff".
- */
- struct PrivateWindowData
- {
- VTE w;
- int diff1Shown;
- struct ChangeBar **diff1Insertions;
- struct PrivateWindowData *next; /* The next in a list of PrivateWindowData */
- VTE columnWindows[3];
- };
-
- /*
- * This is the top of the list to PrivateWindowData. Whenever a new window is
- * "diff"ed, it is prepended to this list.
- */
- struct PrivateWindowData *topPrivateWindowData;
-
- /*
- * This locates QUED Diff's private window data for a given window, if there is
- * any private window data associated with it. If there is not, it creates that
- * private window data, and returns it.
- */
- static struct PrivateWindowData *
- GetPrivateWindowData(VTE w)
- {
- struct PrivateWindowData *pw;
-
- /*
- * First, locate the existing private window data in the list, if any.
- */
- for ( pw = topPrivateWindowData; pw != NULL; pw = pw->next )
- {
- if ( pw->w == w )
- return (pw); /* Found, return it. */
- }
- /*
- * None found, create a private window data record.
- */
- pw = (void *)NewPtrClear((long)sizeof(*pw));
- pw->w = w;
- pw->next = topPrivateWindowData;
- topPrivateWindowData = pw;
- return (pw);
- }
-
- /*
- * Disposes the struct ChangeBar ** record.
- */
- static void
- DisposeChangeBars (struct ChangeBar **diff)
- {
- DisposHandle ((Handle)diff);
- }
-
- /*
- * Disposes a window's private window data record.
- */
- static void
- DisposePrivateWindowData (struct PrivateWindowData *pw)
- {
- if ( pw->diff1Insertions )
- DisposeChangeBars (pw->diff1Insertions);
- DisposePtr ((void *)pw);
- }
-
- /*
- * Disposes a window's private window data. Do this when a window gets closed.
- */
- static void
- DeletePrivateWindowData(VTE w)
- {
- struct PrivateWindowData **pwLast;
- struct PrivateWindowData *pw;
-
- pwLast = &topPrivateWindowData;
- for ( pwLast = &topPrivateWindowData; (pw = (*pwLast)) != NULL; pwLast = &pw->next )
- {
- if ( pw->w == w )
- {
- (*pwLast) = pw->next;
- DisposePrivateWindowData (pw);
- return;
- }
- }
- }
-
- /*
- * RemoveWindowFromColumns finds all references to a particular window.
- * This would be necessary if a window gets closed.
- */
- static void
- RemoveWindowFromColumns (VTE w)
- {
- struct PrivateWindowData *pw;
- int i;
-
- for ( pw = topPrivateWindowData; pw != NULL; pw = pw->next )
- {
- for ( i = 0; i < 2; i++ )
- {
- if ( pw->columnWindows[i] == w )
- pw->columnWindows[i] = NULL;
- }
- }
- }
-
- /*
- * This sets up a window to have private window data.
- */
- static struct ChangeBar **
- InitializeWindowDiff (VTE w)
- {
- struct PrivateWindowData *pw;
- struct ChangeBar newChangeBar;
-
- RemoveWindowFromColumns (w);
- pw = GetPrivateWindowData(w);
- if ( pw->diff1Insertions )
- DisposeChangeBars (pw->diff1Insertions);
- pw->diff1Insertions = (void *)NewHandle(0L);
- return (pw->diff1Insertions);
- }
-
- /*
- * This associates the column of one window with another. A single window can have up
- * to three columns, and each column can be associated with one window. Thus, a window can
- * be associated with up to three other windows.
- */
- static void
- SetColumnWindows (VTE w, VTE wColumn1, VTE wColumn2, VTE wColumn3)
- {
- struct PrivateWindowData *pw;
- int i;
-
- pw = GetPrivateWindowData (w);
- pw->columnWindows[0] = wColumn1;
- pw->columnWindows[1] = wColumn2;
- pw->columnWindows[2] = wColumn3;
- }
-
- /*
- * This changes the number of "change bar" columns shown for a window to numColumns.
- */
- static void
- SetShowWindowDiff (VTE w, int numColumns)
- {
- struct PrivateWindowData *pw;
- GrafPtr currPort;
-
- pw = GetPrivateWindowData (w);
- if ( pw->diff1Shown != numColumns )
- {
- pw->diff1Shown = numColumns;
- FixScrollBars (w);
- }
- GetPort (&currPort);
- SetPort (w);
- InvalRect (&w->portRect);
- SetPort (currPort);
- }
-
- /*
- * SDrawSmallIcon draws an icon at the given point. It reads the icon from the resource file.
- */
- static void
- SDrawSmallIcon (Point pt, int number, int left, int top, int right, int bottom)
- {
- BitMap thebits;
- Rect dest;
- Rect src;
- static char **SICN_Resource;
-
- if ( ! SICN_Resource || ! *SICN_Resource )
- {
- SICN_Resource = GetResource('SICN', 2000);
- }
-
- HNoPurge (SICN_Resource);
- HLock (SICN_Resource);
-
- thebits.baseAddr = (char *)*SICN_Resource + (number << 5);
- thebits.rowBytes = 2;
- thebits.bounds.top = 0;
- thebits.bounds.left = 0;
- thebits.bounds.bottom = 16;
- thebits.bounds.right = 16;
- src.top = top;
- src.left = left;
- src.bottom = bottom;
- src.right = right;
- topLeft(dest) = pt;
- dest.bottom = dest.top + bottom - top;
- dest.right = dest.left + right - left;
- CopyBits (&thebits, &QDGlobals->thePort->portBits, &src, &dest, srcCopy, NULL);
- HUnlock (SICN_Resource);
- HPurge (SICN_Resource);
- }
-
- /*
- * Given a character in the text, this returns the change bar number that this
- * character is inside. If it is not in a change bar, this routine returns a negative
- * value.
- */
- static long
- GetChangeBarNumber (struct ChangeBar **changeBars, long charno)
- {
- register struct ChangeBar *start, *f;
-
- /*
- * If there are no change bars, just return no value.
- */
- if (!changeBars || !*changeBars)
- return (-2L);
- start = *changeBars;
- /*
- * Find the change bar that this character is in.
- */
- f = (struct ChangeBar *)((char *)start + GetHandleSize((Handle)changeBars) - sizeof(**changeBars));
- while (f > start)
- {
- f --;
- if (f->start <= charno && f->end >= charno)
- return (f - start);
- }
- return (-2L);
- }
-
- /*
- * ShowChangeBars shows the change bars to the left of a line of text.
- *
- * startl is the character offset of the beginning of the line. end is the character offset of the
- * end of the line. changeBars is the change bar record for the current column. barLeft is the
- * position of the first column. numColumns is the number of change bar columns.
- */
- static void
- ShowChangeBars (VTE w, long startl, long end, struct ChangeBar **folds, Rect *lineRect, int barLeft, int numColumns)
- {
- long unfolded;
- int i;
- Point oPnLoc;
- struct ChangeBar *unfolds;
- char state;
- int column;
-
- state = HGetState((Handle)folds);
- HLock ((Handle)folds);
-
- oPnLoc = w->pnLoc;
- unfolded = GetChangeBarNumber(folds, startl);
- {
- unfolds = (*folds) + unfolded;
-
- for ( ; unfolded >= 0 && unfolds->end >= startl ; --unfolded, --unfolds )
- {
- Rect foldrect;
- int i;
-
- for ( column = 0; column < numColumns; column++ )
- {
- int isBlack = FALSE;
-
- if ( unfolds->whichColumns && ! (unfolds->whichColumns & (cColumn1 << column)) )
- continue;
- foldrect = *lineRect;
- foldrect.left = barLeft + (DIFF_PIXELS * column);
- foldrect.right = foldrect.left + DIFF_PIXELS - 1;
- if ( unfolds->end == startl )
- {
- if ( unfolds->start < startl )
- continue;
- foldrect.top -= 3;
- foldrect.bottom = foldrect.top + 6;
- EraseRect (&foldrect);
- FillOval (&foldrect, QDGlobals->black);
- continue;
- }
- if ( (unfolds->whichColumns & (cFillBlack1 << column)) )
- {
- FillRect (&foldrect, QDGlobals->black);
- isBlack = TRUE;
- }
- else
- {
- MoveTo (foldrect.left, foldrect.top);
- LineTo (foldrect.left, foldrect.bottom-1);
- MoveTo (foldrect.right - 1, foldrect.top);
- LineTo (foldrect.right - 1, foldrect.bottom-1);
- }
- unfolds = (*folds) + unfolded;
- if (unfolds->start == startl)
- {
- i = foldrect.bottom;
- i -= foldrect.top;
- if (i > 15)
- i = 15;
- SDrawSmallIcon (topLeft(foldrect), (isBlack? 2: 0), 0, 0, DIFF_PIXELS - 1, i);
- }
- unfolds = (*folds) + unfolded;
- if (unfolds->end == end)
- {
- foldrect.top += 3;
- i = 7;
- i -= foldrect.bottom;
- i += foldrect.top;
- if (i < 0)
- {
- i = 0;
- foldrect.top = foldrect.bottom - 7;
- }
- SDrawSmallIcon (topLeft(foldrect), (isBlack? 3: 1), 0, i, DIFF_PIXELS - 1, 7);
- }
- }
- }
- }
- w->pnLoc = oPnLoc;
-
- HSetState ((Handle)folds, state);
- }
-
- /*
- * DiffShowLeftMarginIcons shows the change bars to the left of a line of text.
- *
- * startl is the character offset of the beginning of the line. end is the character offset of the
- * end of the line. lineRect is the rectangle that the line's rectangle. barPosition is the location
- * of the right side of the change bars. This routine gets called by QUED whenever a line
- * of text is displayed. Thus, this routine also call's QUED's original procedure.
- */
- static int
- DiffShowLeftMarginIcons (w, startl, end, lineRect, barPosition)
- VTE w;
- long startl;
- long end;
- Rect *lineRect;
- int barPosition;
- {
- int numColumns;
-
- /* Call QUED's original first. */
- barPosition = (*OriginalShowLeftMarginIcons)(w, startl, end, lineRect, barPosition);
-
- /* Now, draw our change bars. */
- numColumns = GetPrivateWindowData(w)->diff1Shown;
- barPosition -= DIFF_PIXELS * numColumns;
- if ( numColumns )
- {
- ShowChangeBars (w, startl, end, GetPrivateWindowData(w)->diff1Insertions, lineRect, barPosition, numColumns);
- }
- return (barPosition);
- }
-
- static struct ChangeBar *
- GetScriptChangeBar (VTE otherWindow, int scriptNumber)
- {
- register struct ChangeBar *start, *f;
- struct ChangeBar **folds;
-
- folds = GetPrivateWindowData (otherWindow)->diff1Insertions;
-
- if (!folds || !*folds)
- return (NULL);
- start = *folds;
- f = (struct ChangeBar *)((char *)start + GetHandleSize((Handle)folds) - sizeof(**folds));
- while (f > start)
- {
- f --;
- if (f->scriptNumber == scriptNumber )
- return (f);
- }
- return (NULL);
- }
-
- static void
- SelectScriptNumber (VTE otherWindow, int scriptNumber, long scrollOffset)
- {
- struct ChangeBar *f;
-
- f = GetScriptChangeBar(otherWindow, scriptNumber);
- if ( f )
- {
- SetSelect (f->start, f->end, otherWindow);
- SetVScrollValue (otherWindow, scrollOffset + Char2Line (otherWindow, f->start));
- }
- }
-
- /*
- * This routine gets called when the user clicks to the left of text. It determines
- * if the user clicked on one of the change bars, and if so, it handles it appropriately
- * by selecting the associated text in the other windows.
- */
- static int
- DiffClickLeftMarginIcons (VTE w, long sel, Point where, int *barPosition)
- {
- struct PrivateWindowData *pw;
- int oBarPosition;
- long barNo;
- struct ChangeBar *theBar;
- VTE otherWindow;
- int column;
-
- if ( OriginalClickLeftMarginIcons (w, sel, where, barPosition) )
- return (TRUE);
- pw = GetPrivateWindowData(w);
- oBarPosition = *barPosition;
- *barPosition -= DIFF_PIXELS * pw->diff1Shown;
- if ( where.h < oBarPosition && where.h >= (*barPosition) )
- {
- barNo = GetChangeBarNumber(pw->diff1Insertions, sel);
- if (barNo < 0)
- return (FALSE);
- theBar = (*pw->diff1Insertions) + barNo;
- if ( theBar->end == sel && theBar->start != theBar->end )
- return (FALSE);
-
- column = (where.h - (*barPosition)) / DIFF_PIXELS;
- otherWindow = pw->columnWindows[column];
- if ( otherWindow )
- {
- int scriptNumber = theBar->scriptNumber;
- long start = theBar->start;
- long scrollValue = GetVScrollValue (w) - Char2Line (w, start);
-
- for ( column = 0; column < pw->diff1Shown; column++ )
- {
- otherWindow = pw->columnWindows[column];
- if ( otherWindow != w )
- SelectScriptNumber (otherWindow, theBar->scriptNumber, scrollValue);
- }
- }
- return (TRUE);
- }
- return (FALSE);
- }
-
-
- /*
- * This returns the width of all the change bar columns for a given window.
- * This is called by QUED.
- */
- static int
- DiffGetQuedIconsWidth(VTE w)
- {
- int add;
-
- add = GetPrivateWindowData(w)->diff1Shown * 10;
- return (add + OriginalGetQuedIconsWidth(w));
- }
-
- /*
- * "OffsetMarkers":
- * It displaces anything which might locate a text position
- * when characters are inserted/deleted before that
- * position. Markers and folds are among those things
- * that are displaced.
- *
- * "Loc" is the start of the change. "ndelete" is the number
- * of characters to delete. "length" is the number of
- * characters to insert. If "length" is -1, then TRUE
- * or FALSE is returned, but the markers are NOT displaced.
- * TRUE is returned if there is a marker or fold
- * between "loc" and "loc+ndelete".
- *
- */
- static int
- DiffOffsetTextMarkers (w, loc, ndelete, length)
- VTE w;
- long loc, ndelete, length;
- {
- register struct ChangeBar *mk;
- long mloc;
- struct ChangeBar *me;
- long delta;
- struct ChangeBar **diff;
-
- if ( OriginalOffsetTextMarkers(w, loc, ndelete, length) )
- return (TRUE);
-
- diff = GetPrivateWindowData(w)->diff1Insertions;
- if ( diff )
- {
- delta = length - ndelete;
-
- mk = *diff;
- me = (struct ChangeBar *)((char *)mk + GetHandleSize((Handle)diff) - (sizeof(**diff)));
- while (mk < me)
- {
- mloc = mk->start;
- if (length == -1)
- {
- if ( (mloc >= loc && mloc <= loc+ndelete)
- || (mk->end >= loc && mk->end <= loc+ndelete) )
- {
- return (TRUE);
- }
- }
- else
- {
- if (mloc > loc)
- {
- if (mloc >= loc + ndelete)
- mloc += delta;
- else if (mloc > loc + length)
- mloc = loc + length;
- }
- mk->start = mloc;
- mloc = mk->end;
- if (mloc > loc)
- {
- if (mloc >= loc + ndelete)
- mloc += delta;
- else if (mloc > loc + length)
- mloc = loc + length;
- }
- mk->end = mloc;
- }
- mk++;
- }
- }
- return (FALSE);
- }
-
- /*
- * Determine if this change should be ignored. For example, if "Ignore Blank
- * Lines" is set, and ALL of the information in this change is blank lines,
- * return 0.
- *
- * This routine returns a non-zero value if there are any significant differences.
- * If we are comparing a difference of three files, it returns DIFF_ALL, DIFF_1ST, DIFF_2ND, or
- * diff_3RD depending on which file(s) has significant differences from the other(s).
- */
- static struct diff3_block *
- RemoveIgnoredChanges (struct diff3_block *topscript, int nfiles, struct file_data *files)
- {
- LONG i;
- int j;
- int nontrivial;
- int diff[3];
- struct diff3_block **pPrevious = &topscript;
- struct diff3_block *script;
-
- if ( ! ignore_blank_lines_flag && ! ignore_regexp )
- {
- return (topscript); /* I can't eliminate anything. */
- }
-
- for ( script = topscript; script != NULL; script = *pPrevious )
- {
- diff[0] = diff[1] = diff[2] = 0;
- nontrivial = 0;
- for ( j = 0; j < nfiles; j++ )
- {
- for (i = script->ranges[j][START]; i <= script->ranges[j][END]; i++)
- if ((!ignore_blank_lines_flag || files[j].linbuf[i].length > 1)
- && (!ignore_regexp
- || 0 > re_search (&ignore_regexp_compiled,
- files[j].linbuf[i].text,
- files[j].linbuf[i].length, (LONG)0,
- files[j].linbuf[i].length, NULL))
- )
- {
- nontrivial = 1;
- diff[j] = 1;
- break;
- }
- }
-
- /* If all inserted or deleted lines are ignorable,
- tell the caller to ignore this script. */
- if ( ! nontrivial )
- {
- *pPrevious = script->next;
- free (script);
- continue;
- }
- pPrevious = &script->next;
- if ( nfiles == 2 )
- continue;
- if ( script->correspond != DIFF_ALL )
- continue;
- /* If 3 files, figure out the correct value for "correspond" */
- if ( ! diff[0] && ! diff[1] )
- script->correspond = DIFF_3RD;
- else if ( ! diff[0] && ! diff[2] )
- script->correspond = DIFF_2ND;
- else if ( ! diff[1] && ! diff[2] )
- script->correspond = DIFF_1ST;
- }
- return (topscript);
- }
-
- /*
- * ShowChangeBars3 puts the change bars to the left of two or three
- * windows, according to the differences found in "script".
- */
- static void
- ShowChangeBars3 (struct diff3_block *script, int numDiffs, struct file_data contents[3], VTE w[3])
- {
- struct ChangeBar **(diff[3]);
- struct ChangeBar startEnd;
- LONG start, end;
- int i;
- int scriptNumber = 0;
- int correspond;
-
- bzero (&startEnd, sizeof(startEnd));
- for ( i = 0; i < numDiffs; i++ )
- {
- diff[i] = InitializeWindowDiff(w[i]);
- }
- for ( ; script != NULL; (script = script->link), scriptNumber++ )
- {
- struct file_data *contents0 = &contents[0];
-
- correspond = script->correspond;
- for ( i = 0; i < numDiffs; i++, contents0++ )
- {
- start = script->ranges[i][START];
- end = script->ranges[i][END] + 1;
-
- startEnd.whichColumns = cColumn1; /* Assume this represents a "change" */
- if ( numDiffs == 2 )
- {
- LONG startText, endText;
-
- startText = script->ranges[1 - i][START];
- endText = script->ranges[1 - i][END] + 1;
- if ( startText == endText )
- startEnd.whichColumns |= cFillBlack1; /* This means this represents an "insert". */
- }
- else
- {
- int other;
- LONG startText, endText;
-
- if ( correspond == DIFF_ALL || i == correspond - DIFF_1ST )
- {
- /* Put into both columns. */
- startEnd.whichColumns = cColumn1 | cColumn2;
- }
- else
- {
- if ( (i + 2) % 3 == correspond - DIFF_1ST )
- startEnd.whichColumns = cColumn2;
- }
- other = (i + 1) % 3;
- startText = script->ranges[other][START];
- endText = script->ranges[other][END] + 1;
- if ( startText == endText )
- startEnd.whichColumns |= cFillBlack1;
- other = (i + 2) % 3;
- startText = script->ranges[other][START];
- endText = script->ranges[other][END] + 1;
- if ( startText == endText )
- startEnd.whichColumns |= cFillBlack2;
- }
- startEnd.start = contents0->linbuf[start].text - contents0->buffer;
- startEnd.end = contents0->linbuf[end - 1].text + contents0->linbuf[end - 1].length - contents0->buffer;
- startEnd.scriptNumber = scriptNumber;
- PtrAndHand (&startEnd, (Handle)diff[i], (long)sizeof(startEnd));
- }
- }
- startEnd.start = startEnd.end = 0x7FFFFFFF;
- for ( i = 0; i < numDiffs; i++ )
- {
- startEnd.scriptNumber = scriptNumber;
- PtrAndHand (&startEnd, (Handle)diff[i], (long)sizeof(startEnd));
- SetShowWindowDiff (w[i], numDiffs - 1);
- }
- }
-
- /*
- * Merge3FilesFromBase merges w[1] and w[2] into w[0] and puts the result into wMerge (which
- * may be the same as w[0]). It also puts change bars to the left of these windows. "script" is
- * the diff script.
- */
- static void
- Merge3FilesFromBase (struct diff3_block *script, struct file_data contents[3], VTE wMerge, int showChangeBarsOnly, VTE w[3])
- {
- char *startText;
- char *endText;
- int i;
- int conflict;
- Handle theChange;
- char str[256];
- int firstFile, lastFile;
- long mergeOffset = 0;
- struct ChangeBar **diff;
- struct ChangeBar startEnd;
- int scriptNumber = 0;
- int correspond;
-
- bzero (&startEnd, sizeof(startEnd));
- if ( showChangeBarsOnly )
- {
- diff = InitializeWindowDiff(wMerge);
- }
- else
- {
- SetupChanges ("\pMerge 3 Files");
- }
- for ( ; script != NULL; (script = script->link), scriptNumber++ )
- {
- correspond = script->correspond;
- if ( ! showChangeBarsOnly )
- theChange = NewHandle(0L);
- firstFile = lastFile = 2;
- conflict = FALSE;
- /* The way we merge the files depends on which ones are different than the others. */
- switch ( correspond )
- {
- case DIFF_ALL:
- /* Both files 2 and 3 were changed in different ways wrt file 1. Output
- the results of all three. */
- conflict = TRUE;
- firstFile = 0;
- break;
- case DIFF_2ND:
- firstFile = lastFile = 1;
- break;
- }
- for ( i = firstFile; i <= lastFile; i++ )
- {
- if ( conflict )
- {
- long size;
-
- Qued_sprintf (str, i? (i == 1? ">>>>>>> %s(%d)\r": "<<<<<<< %s(%d)\r"): "======= %s(%d)\r", contents[i].name, i);
- size = strlen(str);
- if ( ! showChangeBarsOnly )
- PtrAndHand (str, theChange, size);
- mergeOffset += size;
- }
- startText = contents[i].linbuf[script->ranges[i][START]].text;
- endText = contents[i].linbuf[script->ranges[i][END]].text + contents[i].linbuf[script->ranges[i][END]].length;
- if ( ! showChangeBarsOnly )
- PtrAndHand (startText, theChange, (long)endText - (long)startText);
- if ( showChangeBarsOnly )
- {
- startEnd.whichColumns = (cColumn1 << i);
- if ( correspond == DIFF_1ST )
- startEnd.whichColumns = (cColumn2 | cColumn3);
- if ( ! conflict && script->ranges[0][START] != script->ranges[0][END] + 1 )
- {
- char *startText, *endText;
-
- startText = contents[0].linbuf[script->ranges[0][START]].text;
- endText = contents[0].linbuf[script->ranges[0][END]].text + contents[0].linbuf[script->ranges[0][END]].length;
- startEnd.whichColumns |= (cFillBlack1 << i);
- if ( correspond == DIFF_1ST )
- startEnd.whichColumns |= (cFillBlack2 | cFillBlack3);
- }
- startEnd.start = contents[0].linbuf[script->ranges[0][START]].text - contents[0].buffer + mergeOffset;
- startEnd.end = startEnd.start + endText - startText;
- startEnd.scriptNumber = scriptNumber;
- PtrAndHand (&startEnd, (Handle)diff, (long)sizeof(startEnd));
- }
- mergeOffset += (long)endText - (long)startText;
- }
- if ( conflict )
- {
- long size;
-
- Qued_sprintf (str, "=======\r");
- size = strlen(str);
- if ( ! showChangeBarsOnly )
- PtrAndHand (str, theChange, size);
- mergeOffset += size;
- }
- startText = contents[0].linbuf[script->ranges[0][START]].text;
- endText = contents[0].linbuf[script->ranges[0][END]].text + contents[0].linbuf[script->ranges[0][END]].length;
- mergeOffset -= endText - startText;
- if ( ! showChangeBarsOnly )
- {
- AddChanges (wMerge, startText - contents[0].buffer, endText - startText, -1L, (char *)theChange);
- }
- }
- if ( showChangeBarsOnly )
- {
- startEnd.start = startEnd.end = 0x7FFFFFFF;
- startEnd.scriptNumber = scriptNumber;
- PtrAndHand (&startEnd, (Handle)diff, (long)sizeof(startEnd));
- SetShowWindowDiff (wMerge, 3);
- }
- }
-
- /*
- * This coelesces the contents of two or three files (depending on the value of numDiffs), according
- * to the diff script placed in "script". The
- * files' contents are in w[0], w[1], and possibly w[2]. The result should be put into wMerge,
- * which may be the same as w[0].
- */
- static void
- MergeFiles (struct diff3_block *script, int numDiffs, struct file_data contents[3], VTE wMerge, int showChangeBarsOnly, VTE w[3])
- {
- char *startText;
- char *endText;
- int i;
- struct ChangeBar startEndx;
- struct ChangeBar startEnd;
- long mergeOffset = 0;
- struct ChangeBar **diff;
- LONG end1change;
- int scriptNumber = 0;
- int correspond;
-
- bzero (&startEndx, sizeof(startEndx));
- bzero (&startEnd, sizeof(startEnd));
- if ( showChangeBarsOnly )
- {
- diff = InitializeWindowDiff(wMerge);
- }
- else
- SetupChanges ("\pCoelesce Files");
- for ( ; script != NULL; (script = script->link), scriptNumber++ )
- {
- correspond = script->correspond;
- startEndx.start = contents[0].linbuf[script->ranges[0][START]].text - contents[0].buffer + mergeOffset;
- end1change = contents[0].linbuf[script->ranges[0][END]].text + contents[0].linbuf[script->ranges[0][END]].length - contents[0].buffer;
- startEndx.end = end1change + mergeOffset;
- if ( showChangeBarsOnly )
- {
- if ( startEndx.end > startEndx.start )
- {
- startEndx.whichColumns = cColumn1;
- if ( numDiffs == 3 )
- {
- if ( correspond == DIFF_2ND )
- startEndx.whichColumns = (cColumn1 | cColumn3);
- if ( correspond == DIFF_3RD )
- startEndx.whichColumns = (cColumn1 | cColumn2);
- }
- startEndx.scriptNumber = scriptNumber;
- PtrAndHand (&startEndx, (Handle)diff, (long)sizeof(startEndx));
- }
- }
- for ( i = 1; i < numDiffs; i++ )
- {
- if ( numDiffs == 3 )
- {
- if ( i == 2 && ( correspond == DIFF_1ST || correspond == DIFF_2ND ) )
- continue; /* Ignore this case. */
- if ( i == 1 && ( correspond == DIFF_3RD ) )
- continue; /* Ignore this case. */
- }
- startText = contents[i].linbuf[script->ranges[i][START]].text;
- endText = contents[i].linbuf[script->ranges[i][END]].text + contents[i].linbuf[script->ranges[i][END]].length;
- if ( endText != startText )
- {
- if ( showChangeBarsOnly )
- {
- startEnd.start = startEndx.end;
- startEnd.end = startEnd.start + endText - startText;
- startEnd.whichColumns = (cColumn1 << i);
- if ( numDiffs == 3 && correspond == DIFF_1ST )
- startEnd.whichColumns = (cColumn2 | cColumn3);
- startEnd.scriptNumber = scriptNumber;
- PtrAndHand (&startEnd, (Handle)diff, (long)sizeof(startEnd));
- }
- else if ( startText != endText )
- {
- AddChanges (wMerge, end1change, 0L, endText - startText, startText);
- }
- mergeOffset += endText - startText;
- startEndx.end += endText - startText;
- }
- }
- }
- if ( showChangeBarsOnly )
- {
- startEnd.start = startEnd.end = 0x7FFFFFFF;
- startEnd.scriptNumber = scriptNumber;
- PtrAndHand (&startEnd, (Handle)diff, (long)sizeof(startEnd));
- SetShowWindowDiff (wMerge, numDiffs);
- }
- }
-
- /*
- * This executes the menu command "2-File Differences" or "3-File Differences" depending
- * on the flag doDiff3.
- */
- static void
- DoDiffMenu (Boolean doDiff3)
- {
- struct file_data filevec[4];
- struct file_data contents[3];
- WindowPtr wNew = NULL;
- Handle firstText, secondText;
- struct change *script;
- int printSeparate = TRUE;
- int mergeFiles = FALSE;
- int mergeFromBase = FALSE;
- long size;
- int executeFlag = FALSE;
- VTE wArray[3];
- VTE wMerge = NULL;
- int mapping[3] = { 0, 1, 2 };
- char fileNames[3][256];
- FILE theOutputFile;
-
- /* This prevents calls to "putc" from screwing up. */
- /* Make both "outfile" and "stdout" direct output to our new window! */
- bzero (&theOutputFile, sizeof(theOutputFile));
- outfile = &theOutputFile;
-
- /*
- * This sets the various "globals" used by the DIFF program.
- */
- {
- /*
- * Initialize the global flags, and then set them up according to our
- * last chosen values from the Diff Options... dialog.
- */
- ignore_space_change_flag = (diffOptions.ignoreMultipleBlanks != 0);
- ignore_blank_lines_flag = (diffOptions.ignoreBlankLines != 0);
- length_varies = (ignore_space_change_flag || ignore_all_space_flag);
- ignore_all_space_flag = (diffOptions.ignoreAllBlanks != 0);
- ignore_case_flag = (diffOptions.ignoreCase != 0);
- heuristic = (diffOptions.fastCompare != 0);
- paginate_flag = TRUE;
- always_text_flag = TRUE;
- function_regexp = NULL;
- ignore_regexp = NULL;
- ignore_regexp_compiled.fastmap = NULL;
- function_regexp_compiled.fastmap = NULL;
- bzero (&ignore_regexp_compiled, sizeof ignore_regexp_compiled);
- bzero (&function_regexp_compiled, sizeof function_regexp_compiled);
- if ( diffOptions.ignoreLinesContaining )
- {
- char *val;
- ignore_regexp = diffOptions.linesContaining;
- val = re_compile_pattern (ignore_regexp, strlen (ignore_regexp),
- &ignore_regexp_compiled);
- if (val != 0)
- goto done;
- /* error ("-I option: ", val); */
- ignore_regexp_compiled.fastmap = (char *) xmalloc ((size_t)256);
- }
- output_style = 0;
- context = 0;
- switch (doDiff3? diffOptions.presentCompareResult3 + 100: diffOptions.presentCompareResult2)
- {
- case cShowChangeBars2:
- case cShowChangeBars3 + 100:
- printSeparate = FALSE;
- break;
-
- case cMerge3 + 100:
- mergeFromBase = TRUE;
- /* Float on through */
-
- case cIfdef2:
- if ( diffOptions.ifdef[0] )
- {
- output_style = OUTPUT_IFDEF;
- ifdef_string = diffOptions.ifdef;
- break;
- }
- /* Otherwise, float on through and create a composite window. */
-
- case cComposite2:
- case cComposite3 + 100:
- printSeparate = FALSE;
- mergeFiles = TRUE;
- break;
-
- case cUnified2:
- output_style = OUTPUT_UNIFIED;
- context = 0;
- goto unified;
-
- case cUNIX2:
- case cUNIX3 + 100:
- output_style = OUTPUT_NORMAL;
- if ( diffOptions.isContext || diffOptions.linePreceedingIs )
- {
- output_style = OUTPUT_CONTEXT;
- unified:
- if ( diffOptions.isContext )
- context = diffOptions.contextLines;
- if ( diffOptions.linePreceedingIs )
- {
- char *val;
-
- function_regexp = diffOptions.linePreceeding;
- val = re_compile_pattern (function_regexp, strlen (function_regexp),
- &function_regexp_compiled);
- if (val != 0)
- goto done;
- /* error ("-F option: ", val); */
- function_regexp_compiled.fastmap = (char *) xmalloc ((size_t)256);
- }
- }
- break;
- case cED2:
- output_style = OUTPUT_ED;
- break;
-
- case cForwardED2:
- output_style = OUTPUT_FORWARD_ED;
- break;
-
- case cRCS2:
- output_style = OUTPUT_RCS;
- break;
- }
- }
-
- /*
- * Initialize stdout.
- */
- outFileHandle = NULL; /* Stdout will append to this handle. */
- {
- int file_differs;
-
- /*
- * Get the windows to operate on.
- */
- wArray[0] = NextFileWindow(NULL);
- wArray[1] = NextFileWindow(wArray[0]);
- wArray[2] = NextFileWindow(wArray[1]);
-
- /*
- * If there aren't enough windows, just exit.
- */
- if ( ! wArray[0] || ! wArray[1] || (doDiff3 && ! wArray[2]) )
- goto done;
-
- wMerge = wArray[0];
-
- /*
- * Create a new window if they specified.
- */
- if ( printSeparate || ( ! diffOptions.replaceTopWindow && mergeFiles ) )
- {
- wNew = NewFile();
-
- if ( ! wNew )
- goto done;
- }
-
- firstText = GetWindowText(wArray[0]);
-
- outFileHandle = GetWindowText(wNew);
- SetHandleSize (outFileHandle, 0L);
- if ( ! diffOptions.replaceTopWindow && mergeFiles )
- {
- long size;
-
- SetHandleSize (outFileHandle, size = GetHandleSize(firstText));
- if ( MemErr )
- {
- KillTextWindow (wNew);
- goto done;
- }
- BlockMove (*firstText, *outFileHandle, size);
- firstText = outFileHandle;
- outFileHandle = NULL;
- wMerge = wNew;
- }
-
- secondText = GetWindowText(wArray[1]);
- PtrAndHand ("\r\r", firstText, 2L);
- PtrAndHand ("\r\r", secondText, 2L);
-
- line_end_char = NEWLINE;
-
- bzero (&filevec, sizeof(filevec));
- bzero (&contents, sizeof(filevec));
-
- contents[0].buffered_chars = GetHandleSize(firstText) - 1;
- contents[1].buffered_chars = GetHandleSize(secondText) - 1;
-
- GetWTitle (wArray[0], (unsigned char *)fileNames[0]);
- PtoCstr ((void *)fileNames[0]);
- contents[0].name = fileNames[0];
-
- GetWTitle (wArray[1], (unsigned char *)fileNames[1]);
- PtoCstr ((void *)fileNames[1]);
- contents[1].name = fileNames[1];
-
- MoveHHi (firstText);
- MoveHHi (secondText);
- HLock (secondText);
- MoveHHi (firstText);
- HLock (firstText);
- contents[0].buffer = *firstText;
- contents[1].buffer = *secondText;
-
- filevec[0] = contents[0];
- filevec[1] = contents[1];
-
- script = diff_2_files_no_print (&filevec[0], &file_differs);
-
- contents[0] = filevec[0];
- contents[1] = filevec[1];
-
- if ( doDiff3 )
- {
- Handle thirdText;
- struct change *script2;
- struct diff3_block *diff;
-
- thirdText = GetWindowText(wArray[2]);
- PtrAndHand ("\r\r", thirdText, 2L);
- MoveHHi (thirdText);
- HLock (thirdText);
- contents[2].buffered_chars = GetHandleSize(thirdText) - 1;
- contents[2].buffer = *thirdText;
-
- GetWTitle (wArray[2], (unsigned char *)fileNames[2]);
- PtoCstr ((void *)fileNames[2]);
- contents[2].name = fileNames[2];
-
- filevec[2] = contents[0];
- filevec[3] = contents[2];
- script2 = diff_2_files_no_print (&filevec[2], &file_differs);
-
- contents[0] = filevec[2];
- contents[2] = filevec[3];
-
- BlockMove (contents, diff3_file_data, (long)sizeof(contents));
-
- diff = make_3way_diff (script, script2);
- diff = RemoveIgnoredChanges (diff, 3, contents);
- script = NULL; /* So the later call to dispose_script does nothing */
- if ( diff )
- {
- if ( diffOptions.showChangeBars )
- {
- ShowChangeBars3 (diff, 3, contents, wArray);
- SetColumnWindows (wArray[0], wArray[1], wArray[2], NULL);
- SetColumnWindows (wArray[1], wArray[2], wArray[0], NULL);
- SetColumnWindows (wArray[2], wArray[0], wArray[1], NULL);
- }
-
- if ( printSeparate )
- {
- output_diff3 ( NULL, diff, mapping, mapping);
- }
- else if ( mergeFiles )
- {
- if ( mergeFromBase )
- {
- Merge3FilesFromBase (diff, contents, wMerge, FALSE, wArray);
- }
- else
- {
- MergeFiles (diff, 3, contents, wMerge, FALSE, wArray);
- }
- if ( diffOptions.showChangeBars )
- SetColumnWindows (wMerge, wArray[0], wArray[1], wArray[2]);
- executeFlag = TRUE;
- }
- else if ( ! diffOptions.showChangeBars )
- {
- ShowChangeBars3 (diff, 3, contents, wArray);
- SetColumnWindows (wArray[0], wArray[1], wArray[2], NULL);
- SetColumnWindows (wArray[1], wArray[2], wArray[0], NULL);
- SetColumnWindows (wArray[2], wArray[0], wArray[1], NULL);
- }
- }
- HUnlock (thirdText);
- SetHandleSize (thirdText, GetHandleSize(thirdText) - 2);
- script = (struct change *)diff;
- }
- else
- {
-
- if ( printSeparate )
- {
- print_results (filevec, script, 0);
- script = (struct change *)RemoveIgnoredChanges ((struct diff3_block *)script, 2, contents);
- if ( diffOptions.showChangeBars )
- {
- ShowChangeBars3 ((struct diff3_block *)script, 2, contents, wArray);
- SetColumnWindows (wArray[0], wArray[1], NULL, NULL);
- SetColumnWindows (wArray[1], wArray[0], NULL, NULL);
- }
- }
- else
- {
- script = (struct change *)RemoveIgnoredChanges ((struct diff3_block *)script, 2, contents);
- if ( diffOptions.showChangeBars )
- {
- ShowChangeBars3 ((struct diff3_block *)script, 2, contents, wArray);
- SetColumnWindows (wArray[0], wArray[1], NULL, NULL);
- SetColumnWindows (wArray[1], wArray[0], NULL, NULL);
- }
- if ( mergeFiles )
- {
- MergeFiles ((struct diff3_block *)script, 2, contents, wMerge, FALSE, wArray);
- if ( diffOptions.showChangeBars )
- SetColumnWindows (wMerge, wArray[0], wArray[1], NULL);
- executeFlag = TRUE;
- }
- else if ( ! diffOptions.showChangeBars )
- {
- ShowChangeBars3 ((struct diff3_block *)script, 2, contents, wArray);
- SetColumnWindows (wArray[0], wArray[1], NULL, NULL);
- SetColumnWindows (wArray[1], wArray[0], NULL, NULL);
- }
- }
- }
- if ( ! executeFlag ) /* I will need this afterwards. */
- {
- dispose_script (script);
- {
- int i;
-
- for (i = 0; i <= 2; ++i)
- {
- if ( contents[i].linbuf )
- free (contents[i].linbuf);
- }
- }
- }
- HUnlock (firstText);
- HUnlock (secondText);
- SetHandleSize (firstText, GetHandleSize(firstText) - 2);
- SetHandleSize (secondText, GetHandleSize(secondText) - 2);
- if ( wNew )
- RecalcWindow (wNew);
- if ( executeFlag )
- {
- if ( ExecuteTextChanges () )
- {
- if ( mergeFromBase )
- {
- Merge3FilesFromBase ((struct diff3_block *)script, contents, wMerge, TRUE, wArray);
- }
- else
- {
- MergeFiles ((struct diff3_block *)script, doDiff3? 3: 2, contents, wMerge, TRUE, wArray);
- }
- if ( diffOptions.showChangeBars )
- SetColumnWindows(wMerge, wArray[0], wArray[1], wArray[2]);
- }
- dispose_script (script);
- {
- int i;
-
- for (i = 0; i <= 2; ++i)
- {
- if ( contents[i].linbuf )
- free (contents[i].linbuf);
- }
- }
- }
- }
- done:
- free (ignore_regexp_compiled.fastmap);
- ignore_regexp_compiled.fastmap = NULL;
- free (ignore_regexp_compiled.buffer);
- ignore_regexp_compiled.buffer = NULL;
- free (function_regexp_compiled.fastmap);
- function_regexp_compiled.fastmap = NULL;
- free (function_regexp_compiled.buffer);
- function_regexp_compiled.buffer = NULL;
- if ( allocatedBlocks != 0 )
- {
- #ifdef DEBUGGING
- DebugStr ("\pallocatedBlocks != 0");
- #endif
- allocatedBlocks = 0;
- }
- }
-
- static void
- DoDiffMenu3 (MenuHandle mh, int theItem)
- {
- DoDiffMenu (TRUE);
- }
-
- static void
- DoDiffMenu2 (MenuHandle mh, int theItem)
- {
- DoDiffMenu (FALSE);
- }
-
- static void
- ShowHideItems (VTE w, int firstItem, int lastItem, int show)
- {
- for ( ; firstItem <= lastItem; firstItem++ )
- {
- if ( show )
- ShowDItem (w, firstItem);
- else
- HideDItem (w, firstItem);
- }
- }
-
- /*
- * GetItemControl:
- * Get the control Handle for a particular Item number in a dialog.
- */
- static ControlHandle
- GetItemControl (dialog, itemno)
- VTE dialog;
- int itemno;
- {
- Rect box;
- Handle Item;
- short type;
-
- GetDItem(dialog, itemno, &type, &Item, &box);
- return ((ControlHandle)Item);
- }
-
- /*
- * GetItemValue:
- * Get the value of a control in the dialog box.
- */
- static int
- GetItemValue (dialog, itemno)
- VTE dialog;
- int itemno;
- {
- return (GetCtlValue(GetItemControl (dialog, itemno)));
- }
-
- /*
- * Make sure that the correct items are hidden/shown depending upon the currently
- * chosen settings.
- */
- static void
- ValidateDialog (VTE w, int itemHit)
- {
- int value2, value3;
-
- value2 = GetItemValue (w, DITEM_TWOFILES);
- value3 = GetItemValue (w, DITEM_THREEFILES);
- ShowHideItems (w, DITEM_FIRSTWINDOW, DITEM_LASTWINDOW, value2 == cComposite2 || value3 == cComposite3 || value3 == cMerge3 );
- ShowHideItems (w, DITEM_FIRSTUNIX, DITEM_LASTUNIX, value2 == cUNIX2 || value2 == cUnified2 );
- ShowHideItems (w, DITEM_FIRSTSHOWCHANGEBARS, DITEM_LASTSHOWCHANGEBARS, value2 != cShowChangeBars2 || value3 != cShowChangeBars3 );
- ShowHideItems (w, DITEM_FIRSTIFDEF, DITEM_LASTIFDEF, value2 == cIfdef2 );
- }
-
- /*
- * This executes the "Differences Options..." command on the menu. It displays the options
- * dialog and changes the settings.
- */
- static void
- DoDiffOptions (MenuHandle mh, int theItem, void *valuePtr, long mainFunc)
- {
- WindowPtr d;
- short itemHit;
- short type;
- Handle h;
- Rect box;
-
- diffOptions.ifdefLength = diffOptions.linePreceedingLength = diffOptions.linesContainingLength = -256;
- mh = GetMenu (2000);
- (*mh)->menuID = 2000;
- InsertMenu (mh, -1);
- d = CreateUserDialog (2000, NULL, KillUserDialog);
- SwapStructureWithDialog (d, TRUE, &diffOptions, (long)sizeof(diffOptions), 0);
-
- ValidateDialog (d, itemHit);
- ShowWindow (d);
-
- do
- {
- ModalDialog (FilterDialogEvent, &itemHit);
- GetDItem (d, itemHit, &type, &h, &box);
- DialogButton (d, itemHit);
- ValidateDialog (d, itemHit);
- } while (type != ctrlItem + btnCtrl);
-
- if ( itemHit != 2 )
- SwapStructureWithDialog (d, FALSE, &diffOptions, (long)sizeof(diffOptions), 0);
- KillUserDialog (d);
- DeleteMenu (2000);
- }
-
- /*
- * This is execute when the preferences are read in. This gives the Diff module
- * a chance to read in its own preferences.
- */
- static void
- DiffReadPreferences(void)
- {
- struct DiffOptions **defaultStffHndl;
-
- defaultStffHndl = (struct DiffOptions **) Get1Resource ('DIFF', 256);
- if (defaultStffHndl && GetHandleSize((Handle)defaultStffHndl) == sizeof(struct DiffOptions))
- {
- diffOptions = **defaultStffHndl;
- ReleaseResource ((Handle)defaultStffHndl);
- }
- (*OriginalReadPreferences) ();
- }
-
- /*
- * This gets execute when the user chooses Save Preferences... .
- */
- static void
- DiffSavePreferences(void)
- {
- struct DiffOptions **defs;
- int theError = 0;
-
- if (!(defs = (struct DiffOptions **)Get1Resource('DIFF', 256)))
- {
- defs = (void *)NewHandle(0L);
- AddResource ((Handle)defs, 'DIFF', 256, "\p");
- theError = ResErr;
- }
- PtrToXHand (&diffOptions, (Handle)defs, (long)sizeof(diffOptions));
- ResErr = theError;
- if ( ! ResErr )
- ChangedResource ((Handle)defs);
- if (!ResErr)
- WriteResource ((Handle)defs);
- /* if (ResErr)
- Warn (CStrings[STR_BADSAVEDEFS], ResErr); */
- ReleaseResource ((Handle)defs);
- (*OriginalSavePreferences) ();
- }
-
- /*
- * This gets executed whenever the user closes a document window. This way the
- * Diff module can dispose of its own stuff as well.
- */
- static void
- DiffKillTextWindow (VTE w)
- {
- RemoveWindowFromColumns (w);
- DeletePrivateWindowData (w);
- OriginalKillTextWindow (w);
- }
-
- /*
- * This gets called at startup.
- * Change the QUED bottlenecks, and insert our own menu items into one of the menus.
- */
- void
- _main (void)
- {
- int newMenuID;
-
- /*
- * Install some of our functions in place of QUEDs bottlenecks. Note that "Q" is a pointer
- * to the ORIGINAL bottlenecks.
- */
-
- /*
- * We want to save and read in our settings for "diff" into the preferences file.
- */
- OriginalReadPreferences = ReadPreferences;
- ReadPreferences = DiffReadPreferences;
-
- /*
- * We need to override how text markers are modified when text is moved. Remember to
- * offset our change bars as well.
- */
- OriginalOffsetTextMarkers = OffsetTextMarkers;
- OffsetTextMarkers = DiffOffsetTextMarkers;
-
- /*
- * We need to tell QUED to show the change bars on the left side.
- */
- OriginalShowLeftMarginIcons = ShowLeftMarginIcons;
- ShowLeftMarginIcons = DiffShowLeftMarginIcons;
-
- /*
- * Tell QUED how to compute the total width of all the icons on the left side of the text.
- */
- OriginalGetQuedIconsWidth = GetQuedIconsWidth;
- GetQuedIconsWidth = DiffGetQuedIconsWidth;
-
- /*
- * Tell QUED how to handle clicks on the icon area to the left of the text.
- */
- OriginalClickLeftMarginIcons = ClickLeftMarginIcons;
- ClickLeftMarginIcons = DiffClickLeftMarginIcons;
-
- /*
- * We need to tell QUED to dispose all our additional stuff whenever it wants to close a window.
- */
- OriginalKillTextWindow = KillTextWindow;
- KillTextWindow = DiffKillTextWindow;
-
- /*
- * Now, insert the menu items.
- */
- newMenuID = 260; /* The "memory" menu */
- InsertQuedMenuItem (&newMenuID, 13, "\p", "\p2-File Differences", 'DIFF', 0, DoDiffMenu2, NULL, NULL, 0/* MS_TwoTextWindows | MS_NoModalDialog */);
- InsertQuedMenuItem (&newMenuID, 14, "\p", "\p3-File Differences", 'DIFF', 1, DoDiffMenu3, NULL, NULL, 0/* MS_TwoTextWindows | MS_NoModalDialog */);
- InsertQuedMenuItem (&newMenuID, 15, "\p", "\pDifferences Options…", 'DIFF', 2, DoDiffOptions, NULL, NULL, 0/* MS_TwoTextWindows | MS_NoModalDialog */);
- }
-
- /*
- * All of the following routines are to modify the behavior of UNIX Diff. These are routines
- * that they call from stdio, which we needed to override because QUED doesn't have stdio.
- * Stdio instead appends the output to "outFileHandle".
- */
- size_t
- fwrite (const void *p, size_t len, size_t size, FILE *outfile)
- {
- long retval;
-
- retval = (long)len * (long)size;
- PtrAndHand (p, outFileHandle, retval);
- return (retval);
- }
-
- static void
- ConvertNewLines (char *xstr)
- {
- register char *str = xstr;
-
- while (*str != '\0')
- if (*str++ == '\n')
- str[-1] = '\r';
- }
-
- int
- fprintf (FILE *outfile, const char *fmt, ...)
- {
- va_list arglist;
- char outStr[256];
- long arg1, arg2, arg3, arg4;
- char fmtStr[256];
-
- va_start (arglist, fmt);
-
- strncpy (fmtStr, fmt, 256);
- ConvertNewLines (fmtStr);
-
- arg1 = va_arg(arglist, long);
- arg2 = va_arg(arglist, long);
- arg3 = va_arg(arglist, long);
- arg4 = va_arg(arglist, long);
- Qued_sprintf(outStr, fmtStr, arg1, arg2, arg3, arg4);
- fwrite (outStr, (size_t)1, (size_t)strlen(outStr), outfile);
- va_end (arglist);
- return (0);
- }
-
- int
- printf (const char *fmt, ...)
- {
- va_list arglist;
- char outStr[256];
- long arg1, arg2, arg3, arg4;
- char fmtStr[256];
-
- va_start (arglist, fmt);
-
- strncpy (fmtStr, fmt, 256);
- ConvertNewLines (fmtStr);
-
- arg1 = va_arg(arglist, long);
- arg2 = va_arg(arglist, long);
- arg3 = va_arg(arglist, long);
- arg4 = va_arg(arglist, long);
- Qued_sprintf(outStr, fmtStr, arg1, arg2, arg3, arg4);
- fwrite (outStr, (size_t)1, (size_t)strlen(outStr), NULL);
- va_end (arglist);
- return (0);
- }
-
- int
- __putc (int ch, FILE *outfile)
- {
- char c = ch;
-
- fwrite (&c, (size_t)1, (size_t)1, outfile);
- if ( outfile != NULL )
- outfile->cnt = 0; /* Reset the counter to 0; there is no buffer. */
- return (0);
- }
-
-
-
- int errno;
-
- /* malloc a block of memory, with fatal error message if we can't do it. */
-
- void *
- malloc (size)
- size_t size;
- {
- register void *value;
-
- ResrvMem ((long)size);
-
- value = (void *) NewHandleClear ((long)size);
- if ( value )
- {
- allocatedBlocks++;
- HLock (value);
- value = *(Handle)value;
- }
- else
- {
- if ( ! errno )
- errno = MemErr;
- }
- return value;
- }
-
- /* malloc a block of memory, with fatal error message if we can't do it. */
-
- void *
- xmalloc (size)
- size_t size;
- {
- void *value = malloc((size_t)size);
-
- /* Display an error message if NIL */
- return (value);
- }
-
- /* realloc a block of memory, with fatal error message if we can't do it. */
-
- void *
- realloc (old, size)
- void *old;
- size_t size;
- {
- old = RecoverHandle(old);
- if ( MemErr )
- {
- #ifdef DEBUGGING
- DebugStr ("\pFATAL realloc: Cannot RecoverHandle!");
- #endif
- goto err;
- }
- if ( old )
- {
- HUnlock (old);
- if ( size > GetHandleSize(old))
- ResrvMem ((long)size);
- SetHandleSize (old, (long)size);
- if ( ! MemErr )
- {
- HLock (old);
- old = *(Handle)old;
- return (old);
- }
- DisposHandle (old);
- if ( MemErr )
- {
- #ifdef DEBUGGING
- DebugStr ("\pFATAL realloc: Cannot DisposHandle!");
- #endif
- goto err;
- }
- allocatedBlocks--;
- }
- err:
- if ( ! errno )
- errno = MemErr;
- return (NULL);
- }
-
- /* realloc a block of memory, with fatal error message if we can't do it. */
-
- void *
- xrealloc (old, size)
- void *old;
- size_t size;
- {
- old = realloc(old, (size_t)size);
-
- /* Display an error message if NIL */
- return (old);
- }
-
- void *
- xcalloc (nitems, size)
- size_t nitems;
- size_t size;
- {
- register void *value;
-
- ResrvMem ((long)size);
-
- value = (void *) NewHandleClear ((long)size * (long)nitems);
- if ( value )
- {
- allocatedBlocks++;
- HLock (value);
- value = *(Handle)value;
- }
- else
- {
- if ( ! errno )
- errno = MemErr;
- }
- return value;
- }
-
- void
- free(void *p)
- {
- if ( ! p )
- return;
- p = RecoverHandle(p);
- if ( MemErr )
- {
- #ifdef DEBUGGING
- DebugStr ("\pFATAL free: Cannot RecoverHandle!");
- #endif
- return;
- }
- if ( p )
- {
- DisposHandle (p);
- if ( MemErr )
- {
- #ifdef DEBUGGING
- DebugStr ("\pFATAL free: Cannot DisposHandle!");
- #endif
- return;
- }
- allocatedBlocks--;
- }
- }
-
-
- char *
- ctime(const time_t *timer)
- {
- static char timeStr[256];
- char tempTime[256];
-
- IUTimeString (*timer, TRUE, (unsigned char *)tempTime);
- IUDateString (*timer, 0, (unsigned char *)timeStr);
- PtoCstr ((void *)tempTime);
- PtoCstr ((void *)timeStr);
- strcat (timeStr, " ");
- strcat (timeStr, tempTime);
- return (timeStr);
- }
-
- void
- fatal(char *strMessage)
- {
- message ("%s", strMessage, NULL);
- print_message_queue ();
- }
-
-
- /* Call before outputting the results of comparing files NAME0 and NAME1
- to set up OUTFILE, the stdio stream for the output to go to.
-
- Usually, OUTFILE is just stdout. But when -l was specified
- we fork off a `pr' and make OUTFILE a pipe to it.
- `pr' then outputs to our stdout. */
-
- void
- setup_output (name0, name1, depth)
- char *name0, *name1;
- int depth;
- {
- /* Don't do anything on the Mac. */
- }
-
- /* Call after the end of output of diffs for one file.
- Close OUTFILE and get rid of the `pr' subfork. */
-
- void
- finish_output ()
- {
- /* Don't do anything on the Mac. */
- }
-
- /* Use when a system call returns non-zero status and that is fatal. */
-
- void
- pfatal_with_name (text)
- char *text;
- {
- message ("%s: ", text, NULL);
- print_message_queue ();
- }
-